package cn.wzvtcsoft.sys.security.rbac.service;

import cn.wzvtcsoft.common.property.BosProperties;
import cn.wzvtcsoft.sys.constant.SecurityConst;
import cn.wzvtcsoft.sys.entity.Permission;
import cn.wzvtcsoft.sys.entity.RolePermission;
import cn.wzvtcsoft.sys.entity.User;
import cn.wzvtcsoft.sys.entity.UserRole;
import cn.wzvtcsoft.sys.repository.PermissionRepository;
import cn.wzvtcsoft.sys.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * @author swxu_2005@163.com
 */
@Service
public class SecurityServiceImpl {

  @Autowired
  private PermissionRepository permRepository;

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private BosProperties bosProperties;

  /**
   * 查询指定用户可访问的url
   * 当admin更改角色导致缓存无效后，用户可能在未退出的情况下访问，故不能直接用session中的User对象，而是重新查出User对象
   */
  @Cacheable(cacheNames = "userAllowedPaths", key = "#userId")
  public Set<String> getAuthorizedUrls(Long userId) {
    User user = userRepository.getOne(userId);
    Set<String> authorizedUrls;
    // 如果当前登陆的是admin，允许访问所有权限点，否则根据用户的角色查询
    if (Objects.equals(SecurityConst.USER_NUMBER_ADMIN, user.getNumber())) {
      authorizedUrls = permRepository.findAllPaths();
    } else {
      authorizedUrls = new HashSet<>();
      for (UserRole userRole : user.getUserRoles()) {
        for (RolePermission rolePermission : userRole.getRole().getRolePermissions()) {
          Permission permission = rolePermission.getPermission();
          if (permission.getType() == 1) {
            authorizedUrls.add(permission.getPath());
          }
        }
      }
    }
    // 有些权限点是只要登陆了就能访问，如获取当前登陆用户的信息
    authorizedUrls.addAll(bosProperties.getSecurity().getAuthorizedAfterLogin());
    System.out.println("+++++++++++++ 获取用户的授权URL +++++++++++++");
    for (String url : authorizedUrls) {
      System.out.println(url);
    }
    return authorizedUrls;
  }

  /**
   * 查询指定用户可访问的菜单
   */
  @Cacheable(cacheNames = "userInfo", key = "#userId")
  public Set<String> getAuthorizedMenus(Long userId) {
    User user = userRepository.getOne(userId);
    Set<String> authorizedMenus;
    if (Objects.equals(user.getNumber(), SecurityConst.USER_NUMBER_ADMIN)) {
      authorizedMenus = permRepository.findAllMenus();
    } else {
      authorizedMenus = new HashSet<>();
      for (UserRole userRole : user.getUserRoles()) {
        for (RolePermission rolePermission : userRole.getRole().getRolePermissions()) {
          Permission permission = rolePermission.getPermission();
          if (permission.getType() == 0) {
            authorizedMenus.add(permission.getName());
          }
        }
      }
    }
    System.out.println("+++++++++++++ 获取用户的菜单 +++++++++++++");
    for (String menu : authorizedMenus) {
      System.out.println(menu);
    }
    return authorizedMenus;
  }

}
